#ifndef GRIDFACTORY_H
#define GRIDFACTORY_H

#include "../Grid/Grid.h"
#include "../Grid/Grid1D.h"
#include "../Grid/Grid2D.h"
#include "../Grid/Grid3D.h"
#include "../Parallel/ParallelMPI.h"
#include "../Parallel/ParallelMPI2D.h"
#include "../Input/PicParams.h"
#include "../IO/IO.h"

#include "../Tool/Macros.h"

#include <string>

using namespace std;

class GridFactory {
public:

    static Grid* create(PicParams* params_, ParallelMPI* pmpi_, IO* io_)
    {
        Grid* grid = NULL;
        if (params_->geometry == "1d3v")
        {
            grid = new Grid1D(params_, pmpi_);
        }
        else if (params_->geometry == "2d3v" )
        {
    		string gapKind;
            int ny_source;
            int ny_gapHeight;
            int nx_gapWeight;
            int ny_bevel_depth;
            double potential_wall;


            grid = new Grid2D(params_, pmpi_, params_->grid_type, gapKind, ny_source, ny_gapHeight, nx_gapWeight, ny_bevel_depth, potential_wall);

            if(grid->grid_type == "from_file")
            {
                io_->readGrid(grid);
            }
            grid->compute();

            pmpi_->scatterGrid(grid);
        }
        else if ( params_->geometry == "3d3v" )
        {
            string grid_type;
    		string gapKind;
            int ny_source;
            int ny_gapHeight;
            int nx_gapWeight;
            int ny_bevel_depth;
            double potential_wall;

            grid = new Grid3D(params_, pmpi_, params_->grid_type, gapKind, ny_source, ny_gapHeight, nx_gapWeight, ny_bevel_depth, potential_wall);
            if(grid->grid_type == "from_file")
            {
                io_->readGrid(grid);
                log_info<<"reading grid ends";
            }
            grid->compute();
            log_info<<"Grid compute ends";
        }
        else 
        {
            log_error<<"geometry error " << params_->geometry;
        }
        return grid;
    }

};

#endif
